﻿package tools;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;

public class FactoryDemo {
	public static void main(String[] args) {
		Usb usb = NormalFactory.getUsbInstance("mouse");
		usb.plugIn();

		/**
		 * 输入完整类名,比较坑爹,所以可以考虑通过配置文件来保存所有子类的完整路径,为了方便可以使用普通文件保存,项目中应该用xml文件来配置更合适
		 */
		usb = SuperFactory.getUsbInstance("com.javase.other.demo.Mouse");
		usb.plugIn();

		/** 读取并初始化配置文件 */
		Properties prop = SuperFactory.init();
		usb = SuperFactory.getUsbInstance(prop.getProperty("keyboard"));
		usb.plugIn();
	}
}

interface Usb {
	public void plugIn();
}

class Mouse implements Usb {

	@Override
	public void plugIn() {
		System.out.println("Usb Mouse.");
	}

}

class Keyboard implements Usb {

	@Override
	public void plugIn() {
		System.out.println("Usb Keyboard.");
	}

}

/** 普通工厂,如果子类有扩充,那么工厂类必须进行修改 */
class NormalFactory {
	public static Usb getUsbInstance(String name) {
		Usb usb = null;
		if ("mouse".equals(name)) {
			usb = new Mouse();
		}
		if ("keyboard".equals(name)) {
			usb = new Keyboard();
		}
		return usb;
	}
}

/** 超级工厂,如果子类有扩充,那么工厂类无需进行修改 */
class SuperFactory {
	public static Usb getUsbInstance(String className) {
		Usb usb = null;
		try {
			/** 通过反射实现具体的子类 */
			usb = (Usb) Class.forName(className).newInstance();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		return usb;
	}

	public static Properties init() {
		Properties prop = new Properties();
		try {
			prop.load(new FileInputStream(new File(
					"tmpfile\\txt\\FactoryProps.txt")));
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		if (prop.isEmpty()) {
			prop.setProperty("mouse", "com.javase.other.demo.Mouse");
			prop.setProperty("keyboard", "com.javase.other.demo.Keyboard");
			try {
				prop.store(new FileOutputStream(new File(
						"tmpfile\\txt\\FactoryProps.txt")), "FactoryProps");
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return prop;
	}
}
